home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 43 / Amiga Format CD43 (1999)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-09].iso / -serious- / comms / other / ascan / sources / main.c < prev    next >
C/C++ Source or Header  |  1999-06-14  |  8KB  |  309 lines

  1.  
  2. // slink LIB:c.o main.o getopt.o utils.o errors.o ascan.o ddelay.o noopentcp.o to ascan LIB LIB:sc.lib LIB:miami.lib SC SD ND NOICONS
  3.  
  4. #include "ascan.h"
  5. #include <dos/dostags.h>
  6. #include "getopt.h"
  7. #include "ascan_rev.h"
  8.  
  9. /***************************************************************************/
  10.  
  11. #define USAGE_MSG "Usage: %s [-Vhvn] [-c childs] [-p ppt] [-t timeout] <host> [from] [to]\n"
  12.  
  13. #define HELP_MSG USAGE_MSG "\
  14.        -V     version, copyright and greets\n\
  15.        -h     this help\n\
  16.        -v     verbose mode (off)\n\
  17.        -n     output service name (off)\n\
  18.        -c     childs (%ld)\n\
  19.        -p     ports per group (%ld)\n\
  20.        -t     general timeout in seconds (%ld)\n\
  21.        host   host to scan\n\
  22.        from   from port (%ld)\n\
  23.        to     to port (from port if specified, %ld otherwise)\n\n"
  24.  
  25. #define VERSION_MSG VERS " (" DATE ") © alfie\n\
  26. Amiga multi process scanner.\n\
  27. Thanks to:\n\
  28. ircnet/#amyita friends.\n\
  29. all the pc users ascanned on testing.\n"
  30.  
  31. /***************************************************************************/
  32.  
  33. static char _version[] = VERSTAG;
  34. static char _author[] = "Alfonso Ranieri <alfier@iol.it>";
  35.  
  36. /***************************************************************************/
  37.  
  38. /*This is the main entry point  */
  39. /*"Real programmer blah blah blah" - I love "goto" and I use it :) */
  40.  
  41. int main(int argc,char **argv)
  42. {
  43.     struct global            g;
  44.     struct dstruct             ds;
  45.     char                     *endptr = NULL;
  46.     u_long                     host;
  47.     struct MsgPort             reply;
  48.     struct childMsg         *msga, *msg;
  49.     register struct Library *MiamiBase;
  50.     register LONG             sigBit;
  51.     register ULONG             flags;
  52.     register int             x, t, n, ts, f, ended, opt, from, to, gt,
  53.                             nchild, ppt, res = RETURN_ERROR;
  54.  
  55.     /*hummm just compile with no-break option, but I always forget it so... :)*/
  56.     signal(SIGINT,SIG_IGN);
  57.  
  58.     /*must be freed*/
  59.     sigBit = -1;
  60.     memset(&ds,NULL,sizeof(ds));
  61.  
  62.     /* defaults */
  63.     nchild = DEF_NCHILD;
  64.     gt     = DEF_GT;
  65.     ppt    = DEF_PPT;
  66.     from   = DEF_FROM;
  67.     to     = DEF_TO;
  68.     flags  = 0;
  69.  
  70.     while ((opt = getopt(argc,argv,"Vhvnc:p:t:"))!=-1)
  71.     {
  72.         switch (opt)
  73.         {
  74.             case 'V':
  75.                 fprintf(stderr,VERSION_MSG);
  76.                 res = RETURN_OK;
  77.                 goto exit;
  78.                 break;
  79.  
  80.             case 'h':
  81.                 fprintf(stderr,HELP_MSG,PRG,DEF_NCHILD,DEF_PPT,DEF_GT,DEF_FROM,DEF_TO);
  82.                 if (opt=='h') res = RETURN_OK;
  83.                 goto exit;
  84.                 break;
  85.  
  86.             case 'v':
  87.                 flags |= FLG_VERBOSE;
  88.                 break;
  89.  
  90.             case 'n':
  91.                 flags |= FLG_PORTNAME;
  92.                 break;
  93.  
  94.             case 'c':
  95.                 nchild = strtoul(optarg,&endptr,10);
  96.                 if ((*endptr != '\0') || (nchild<1) || (nchild>MAXCHILDS))
  97.                 {
  98.                     fprintf(stderr,"%s: bad childs value '%s'\n",PRG,optarg);
  99.                     goto exit;
  100.                    }
  101.                 break;
  102.  
  103.             case 'p':
  104.                 ppt = strtoul(optarg,&endptr,10);
  105.                 if ((*endptr != '\0') || (ppt<1) || (ppt>MAX_SOCKS_PER_TASK))
  106.                 {
  107.                     fprintf(stderr,"%s: bad ports per group value '%s'\n",PRG,optarg);
  108.                     goto exit;
  109.                    }
  110.                 break;
  111.  
  112.             case 't':
  113.                 gt = strtoul(optarg,&endptr,10);
  114.                 if ((*endptr != '\0') || (gt<0))
  115.                 {
  116.                     fprintf(stderr,"%s: bad general timeout '%s'\n",PRG,optarg);
  117.                     goto exit;
  118.                    }
  119.                 break;
  120.  
  121.             default:
  122.                 fprintf(stderr,USAGE_MSG,PRG);
  123.                 res = RETURN_WARN;
  124.                 goto exit;
  125.                 break;
  126.        }
  127.     }
  128.  
  129.     argc -= optind;
  130.     argv += optind;
  131.  
  132.     if (argc==0 || argc>3)
  133.     {
  134.         if (argc) fprintf(stderr,"%s: too many arguments.\n",PRG);
  135.         fprintf(stderr,USAGE_MSG,PRG);
  136.         goto exit;
  137.     }
  138.  
  139.     if (**argv=='?' && *((*argv)+1)==0)
  140.     {
  141.         fprintf(stderr,USAGE_MSG,PRG);
  142.         res = RETURN_OK;
  143.         goto exit;
  144.     }
  145.  
  146.     if ((host = resolve(*argv))==INADDR_NONE)
  147.     {
  148.         if (SetSignal(0,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
  149.             error(SCAN_ERROR_BREAK,PRG,NULL);
  150.         else error(SCAN_ERROR_TARGETNOTFOUND,PRG,*argv);
  151.         goto exit;
  152.     }
  153.  
  154.     if (argc>1)
  155.     {
  156.         from = strtoul(*(argv+1),&endptr,10);
  157.         if ((*endptr != '\0') || (from<1) || (from>65536))
  158.         {
  159.             fprintf(stderr,"%s: bad from port value '%s'\n",PRG,*(argv+1));
  160.             goto exit;
  161.            }
  162.         if (argc==3)
  163.         {
  164.             to = strtoul(*(argv+2),&endptr,10);
  165.             if ((*endptr != '\0') || (to<1) || (to>65536))
  166.             {
  167.                 fprintf(stderr,"%s: bad to port value '%s'\n",PRG,*(argv+2));
  168.                 goto exit;
  169.                }
  170.             if (to<from)
  171.             {
  172.                 fprintf(stderr,"%s: bad ports range '%d-%d'\n",PRG,from,to);
  173.                 goto exit;
  174.             }
  175.         }
  176.         else to=from;
  177.     }
  178.  
  179.     /* Miami as a dinamic FD stuff, Genesis crashes if >64 sockets*/
  180.     if (MiamiBase=OpenLibrary("miami.library",0)) CloseLibrary(MiamiBase);
  181.     else flags|=FLG_LIMITED;
  182.     g.flags = flags;
  183.  
  184.     g.nchild=nchild;
  185.     if ((ppt>LIMITED_SOCKETS) && (flags & FLG_LIMITED)) ppt=LIMITED_SOCKETS;
  186.     g.ppt=ppt;
  187.     g.from=from;
  188.     g.to=to;
  189.     g.gt=gt;
  190.  
  191.     /*the only things we allocate is the messages array but might be static too*/
  192.     if (!(msga=AllocVec(sizeof(struct childMsg)*nchild,MEMF_PUBLIC|MEMF_CLEAR)) ||
  193.         ((sigBit=AllocSignal(-1))==-1) ||
  194.         !setDStruct(&ds))
  195.     {
  196.         error(SCAN_ERROR_NOMEM,PRG,NULL);
  197.         res = RETURN_FAIL;
  198.         goto end;
  199.     }
  200.     INITPORT(&reply,sigBit);
  201.  
  202.     n = to-from+1;
  203.     ts = n/nchild;
  204.     if (n%nchild) ts++;
  205.     f=from;
  206.  
  207.     if (flags & FLG_VERBOSE) printGlobal(&g,*argv,host);
  208.  
  209.     memset(g.childs,NULL,sizeof(g.childs));
  210.  
  211.     /*let's launch "nchild" ascan processes*/
  212.     for (t = 0; t<nchild; t++)
  213.     {
  214.         /*user wants to stop?*/
  215.         if (SetSignal(0,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
  216.         {
  217.             SetSignal(SIGBREAKF_CTRL_C,SIGBREAKF_CTRL_C);
  218.             goto fin;
  219.         }
  220.  
  221.         INITMESSAGE(MESSAGE(msga+t),&reply,sizeof(struct childMsg));
  222.         sprintf((msga+t)->name,"Ascan-Child[%lx/%ld]",FindTask(NULL),t);
  223.  
  224.         (msga+t)->g     = &g;
  225.         (msga+t)->host  = host;
  226.         (msga+t)->tnum  = t;
  227.         (msga+t)->from  = f;
  228.         (msga+t)->to    = ((f+=ts)>to) ? to : f-1;
  229.  
  230.         if (*(g.childs+t) = CreateNewProcTags(NP_Entry,            ascan,
  231.                                                NP_Input,            Input(),
  232.                                               NP_Output,        Output(),
  233.                                               NP_Name,             NULL,
  234.                                               NP_CloseInput,     FALSE,
  235.                                               NP_CloseOutput,    FALSE,
  236.                                               NP_CopyVars,        FALSE,
  237.                                               NP_StackSize,        8192,
  238.                                               TAG_DONE))
  239.         {
  240.             PutMsg(&(*(g.childs+t))->pr_MsgPort,(struct Message *)(msga+t));
  241.         }
  242.         else
  243.         {
  244.             error(SCAN_ERROR_NOMEM,PRG,NULL);
  245.             res = RETURN_FAIL;
  246.             goto fin;
  247.         }
  248.  
  249.         if (flags & FLG_VERBOSE) fprintf(stderr,"%s: child %s started\n",PRG,(msga+t)->name);
  250.     }
  251.  
  252.     /*the global timeout*/
  253.     if (gt) startDelay(&ds,gt,0);
  254.  
  255. fin:
  256.     for (ended = 0; t>0;)
  257.     {
  258.         /*we wait for ctrl_c timeout or an ascan process end*/
  259.         res = Wait(SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|(1<<sigBit)|(1<<ds.sigBit));
  260.  
  261.         /*a process exited?*/
  262.         while (msg = (struct childMsg *)GetMsg(&reply))
  263.         {
  264.             if (msg->res)
  265.             {
  266.                 if ((msg->res!=SCAN_ERROR_BREAK) || (flags & FLG_VERBOSE))
  267.                     error(msg->res,msg->name,(STRPTR)msg->code);
  268.             }
  269.             else if (flags & FLG_VERBOSE) fprintf(stderr,"%s ended\n",msg->name);
  270.             *(g.childs+msg->tnum) = NULL;
  271.             t--;
  272.         }
  273.  
  274.         /*not implemeted...each process should print infos*/
  275.         if (!ended && (res & SIGBREAKF_CTRL_D))
  276.         {
  277.             Forbid();
  278.             for (x = 0; x<nchild; x++)
  279.                 if (*(g.childs+x)) Signal((struct Task *)*(g.childs+x),SIGBREAKF_CTRL_D);
  280.             Permit();
  281.         }
  282.  
  283.         /*ctrl-c or timeout?*/
  284.         if (!ended && (res & (SIGBREAKF_CTRL_C|(1<<ds.sigBit))))
  285.         {
  286.             /*if so we stop each stil running ascan*/
  287.             if (res & SIGBREAKF_CTRL_C) error(SCAN_ERROR_BREAK,PRG,NULL);
  288.             else error(SCAN_ERROR_TIMEOUT,PRG,NULL);
  289.             Forbid();
  290.             for (x = 0; x<nchild; x++)
  291.                 if (*(g.childs+x)) Signal((struct Task *)*(g.childs+x),SIGBREAKF_CTRL_C);
  292.             Permit();
  293.             ended = 1;
  294.         }
  295.     }
  296.     fprintf(stderr,"\n%s: done.\n",PRG);
  297.     res = RETURN_OK;
  298.  
  299. end:
  300.     freeDStruct(&ds);
  301.     if (sigBit!=-1) FreeSignal(sigBit);
  302.     if (msga) FreeVec(msga);
  303.  
  304. exit:
  305.     exit(res);
  306. }
  307.  
  308. /***************************************************************************/
  309.